package top.lixunda.commerce.common.core.controller.wrapper;

import top.lixunda.commerce.common.core.utils.MyLambdaUtils;
import top.lixunda.commerce.common.core.utils.EntityGetFunction;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author LiXunda
 * @version time:2019/10/14 13:26
 */
public class LambdaQuerySqlWrapper<T> extends AbstractSqlWrapper<T>
        implements ILambdaQuerySqlWrapper<T> {

    private T t = null;

    private QueryEntityBlock<T> entityBlock = new QueryEntityBlock<>();

    @Override
    @SafeVarargs
    final public LambdaQuerySqlWrapper<T> select(EntityGetFunction<T, ?>... columns) {
        getEntityBlock().select(getColumnName(columns));
        return this;
    }

    @Override
    public QueryEntityBlock<T> getEntityBlock() {
        return entityBlock;
    }

    @Override
    public LambdaQuerySqlWrapper selectAll() {
        entityBlock.selectAll();
        return this;
    }

    @Override
    public LambdaQuerySqlWrapper select(String... columns) {
        entityBlock.select(columns);
        return this;
    }

    @Override
    public LambdaQuerySqlWrapper<T> setEntityBlock(QueryEntityBlock<T> entityBlock) {
        this.entityBlock = entityBlock;
        return this;
    }

    @Override
    public BaseDataQuerySqlWrapper<T> toDataQuerySqlWrapper() {
        return (BaseDataQuerySqlWrapper<T>) BaseDataSqlWrapper.fromWrapper(this, new BaseDataQuerySqlWrapper<>());
    }


    @Override
    public LambdaQuerySqlWrapper<T> groupBy(EntityGetFunction<T, ?> column) {
        return (LambdaQuerySqlWrapper<T>) super.groupBy(getColumnName(column));
    }

    @Override
    @SafeVarargs
    final public LambdaQuerySqlWrapper<T> groupBy(EntityGetFunction<T, ?>... columns) {
        return (LambdaQuerySqlWrapper<T>) super.groupBy(getColumnName(columns));
    }

    @Override
    public LambdaQuerySqlWrapper<T> having(EntityGetFunction<T, ?> column) {
        return (LambdaQuerySqlWrapper<T>) super.having(getColumnName(column));
    }

    @Override
    public LambdaQuerySqlWrapper<T> eq(EntityGetFunction<T, ?> column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.eq(getColumnName(column), value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> ne(EntityGetFunction<T, ?> column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.ne(getColumnName(column), value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> gt(EntityGetFunction<T, ?> column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.gt(getColumnName(column), value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> ge(EntityGetFunction<T, ?> column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.ge(getColumnName(column), value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> lt(EntityGetFunction<T, ?> column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.lt(getColumnName(column), value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> le(EntityGetFunction<T, ?> column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.le(getColumnName(column), value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> between(EntityGetFunction<T, ?> column, Object value1, Object value2) {
        return (LambdaQuerySqlWrapper<T>) super.between(getColumnName(column), value1, value2);
    }

    @Override
    public LambdaQuerySqlWrapper<T> notBetween(EntityGetFunction<T, ?> column, Object value1, Object value2) {
        return (LambdaQuerySqlWrapper<T>) super.notBetween(getColumnName(column), value1, value2);
    }

    @Override
    public LambdaQuerySqlWrapper<T> like(EntityGetFunction<T, ?> column, String value) {
        return (LambdaQuerySqlWrapper<T>) super.like(getColumnName(column), value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> notLike(EntityGetFunction<T, ?> column, String value) {
        return (LambdaQuerySqlWrapper<T>) super.notLike(getColumnName(column), value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> likeLeft(EntityGetFunction<T, ?> column, String value) {
        return (LambdaQuerySqlWrapper<T>) super.likeLeft(getColumnName(column), value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> likeRight(EntityGetFunction<T, ?> column, String value) {
        return (LambdaQuerySqlWrapper<T>) super.likeRight(getColumnName(column), value);
    }

    @Override
    @SafeVarargs
    final public LambdaQuerySqlWrapper<T> isNull(EntityGetFunction<T, ?>... column) {
        return (LambdaQuerySqlWrapper<T>) super.isNull(getColumnName(column));
    }

    @Override
    @SafeVarargs
    final public LambdaQuerySqlWrapper<T> isNotNull(EntityGetFunction<T, ?>... column) {
        return (LambdaQuerySqlWrapper<T>) super.isNotNull(getColumnName(column));
    }

    @Override
    public LambdaQuerySqlWrapper<T> in(EntityGetFunction<T, ?> column, List<?> values) {
        return (LambdaQuerySqlWrapper<T>) super.in(getColumnName(column), values);
    }

    @Override
    public LambdaQuerySqlWrapper<T> notIn(EntityGetFunction<T, ?> column, List<?> values) {
        return (LambdaQuerySqlWrapper<T>) super.notIn(getColumnName(column), values);
    }

    @Override
    public LambdaQuerySqlWrapper<T> apply(String applySql, Object... params) {
        return (LambdaQuerySqlWrapper<T>) super.apply(applySql, params);
    }

    @Override
    @SafeVarargs
    final public String[] getColumnName(EntityGetFunction<T, ?>... columns) {
        if (columns == null || columns.length <= 0) {
            return new String[0];
        }
        List<String> list = new ArrayList<>(columns.length);
        for (EntityGetFunction<T, ?> column : columns) {
            list.add(getColumnName(column));
        }
        return list.toArray(new String[]{});
    }

    @Override
    public String getColumnName(EntityGetFunction<T, ?> column) {
        return MyLambdaUtils.getLambdaName(t, column);
    }

    @Override
    public LambdaQuerySqlWrapper<T> orderBy(EntityGetFunction<T, ?> column, String type) {
        return (LambdaQuerySqlWrapper<T>) super.orderBy(getColumnName(column), type);
    }

    @Override
    @SafeVarargs
    final public LambdaQuerySqlWrapper<T> orderByAsc(EntityGetFunction<T, ?>... column) {
        return (LambdaQuerySqlWrapper<T>) super.orderByAsc(getColumnName(column));
    }

    @Override
    @SafeVarargs
    final public LambdaQuerySqlWrapper<T> orderByDesc(EntityGetFunction<T, ?>... column) {
        return (LambdaQuerySqlWrapper<T>) super.orderByDesc(getColumnName(column));
    }

    @Override
    public LambdaQuerySqlWrapper<T> setEntity(T t) {
        return (LambdaQuerySqlWrapper<T>) super.setEntity(t);
    }

    @Override
    public LambdaQuerySqlWrapper<T> groupBy(String... column) {
        return (LambdaQuerySqlWrapper<T>) super.groupBy(column);
    }

    @Override
    public LambdaQuerySqlWrapper<T> orderBy(Map<String, String> map) {
        return (LambdaQuerySqlWrapper<T>) super.orderBy(map);
    }

    @Override
    public LambdaQuerySqlWrapper<T> orderBy(String column, String value) {
        return (LambdaQuerySqlWrapper<T>) super.orderBy(column, value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> orderByAsc(String... columns) {
        return (LambdaQuerySqlWrapper<T>) super.orderByAsc(columns);
    }

    @Override
    public LambdaQuerySqlWrapper<T> orderByDesc(String... columns) {
        return (LambdaQuerySqlWrapper<T>) super.orderByDesc(columns);
    }

    @Override
    public LambdaQuerySqlWrapper<T> having(String column) {
        return (LambdaQuerySqlWrapper<T>) super.having(column);
    }

    @Override
    public LambdaQuerySqlWrapper<T> limit(int start, int count) {
        return (LambdaQuerySqlWrapper<T>) super.limit(start, count);
    }

    @Override
    public LambdaQuerySqlWrapper<T> allEq(Map<String, Object> map) {
        return (LambdaQuerySqlWrapper<T>) super.allEq(map);
    }

    @Override
    public LambdaQuerySqlWrapper<T> eq(String column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.eq(column, value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> ne(String column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.ne(column, value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> gt(String column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.gt(column, value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> ge(String column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.ge(column, value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> lt(String column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.lt(column, value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> le(String column, Object value) {
        return (LambdaQuerySqlWrapper<T>) super.le(column, value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> between(String column, Object value1, Object value2) {
        return (LambdaQuerySqlWrapper<T>) super.between(column, value1, value2);
    }

    @Override
    public LambdaQuerySqlWrapper<T> notBetween(String column, Object value1, Object value2) {
        return (LambdaQuerySqlWrapper<T>) super.notBetween(column, value1, value2);
    }

    @Override
    public LambdaQuerySqlWrapper<T> like(String column, String value) {
        return (LambdaQuerySqlWrapper<T>) super.like(column, value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> notLike(String column, String value) {
        return (LambdaQuerySqlWrapper<T>) super.notLike(column, value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> likeLeft(String column, String value) {
        return (LambdaQuerySqlWrapper<T>) super.likeLeft(column, value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> likeRight(String column, String value) {
        return (LambdaQuerySqlWrapper<T>) super.likeRight(column, value);
    }

    @Override
    public LambdaQuerySqlWrapper<T> isNull(String... column) {
        return (LambdaQuerySqlWrapper<T>) super.isNull(column);
    }

    @Override
    public LambdaQuerySqlWrapper<T> isNotNull(String... column) {
        return (LambdaQuerySqlWrapper<T>) super.isNotNull(column);
    }

    @Override
    public LambdaQuerySqlWrapper<T> in(String column, List<?> values) {
        return (LambdaQuerySqlWrapper<T>) super.in(column, values);
    }

    @Override
    public LambdaQuerySqlWrapper<T> notIn(String column, List<?> values) {
        return (LambdaQuerySqlWrapper<T>) super.notIn(column, values);
    }

    @Override
    public LambdaQuerySqlWrapper<T> or() {
        return (LambdaQuerySqlWrapper<T>) super.or();
    }

    @Override
    public LambdaQuerySqlWrapper<T> and() {
        return (LambdaQuerySqlWrapper<T>) super.and();
    }

    @Override
    public LambdaQuerySqlWrapper<T> or(ConditionBlock sqlBlock) {
        return (LambdaQuerySqlWrapper<T>) super.or(sqlBlock);
    }

    @Override
    public LambdaQuerySqlWrapper<T> and(ConditionBlock sqlBlock) {
        return (LambdaQuerySqlWrapper<T>) super.and(sqlBlock);
    }

    @SuppressWarnings("unused")
    public static <T> LambdaQuerySqlWrapper<T> build(Class<T> tClass) {
        return new LambdaQuerySqlWrapper<>();
    }

}
